package fr.business.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import fr.business.ManageApplicationsBusinessService;
import fr.form.Application;
import fr.form.Participation;
import fr.form.synthese.SyntheseEcranApplications;
import fr.form.synthese.SyntheseApplication;
import fr.form.synthese.SyntheseEcranParticipation;
import fr.persistence.ManageApplicationPersistenceService;
import fr.persistence.ManageParticipationPersistenceService;
import fr.utilities.Constantes;
import fr.utilities.Constantes.StatutApplication;
import fr.utilities.Constantes.StatutApplicationUser;
import fr.utilities.Constantes.StatutParticipation;
import fr.utilities.DateUtil;

@Service
@Transactional
public class ManageApplicationsBusinessServiceImpl 
implements ManageApplicationsBusinessService{

    @Autowired
	private ManageApplicationPersistenceService psApp;

    @Autowired
	private ManageParticipationPersistenceService psParticipation;

    public static final Integer NB1 = 1;
    public static final Integer NB2 = 2;
    public static final Integer NB3 = 3;
    public static final Integer NB4 = 4;
    public static final Integer NB5 = 5;

    public static final String OUI = "Oui";
    public static final String NON = "Non";

    
	public List<Application> getAllApplications() {
		return psApp.readAllObject();
	}
	
	public List<SyntheseApplication> getStartedApplications() {

		List<Application> apps = psApp.getStartedApplications();
		
		List<SyntheseApplication> synApps = new ArrayList<SyntheseApplication>();
		for(Application app : apps){
			synApps.add(applicationToSynthese(app,Constantes.USER));
		}
		
		Collections.sort(synApps);
		
		return synApps;

	}
	
	public SyntheseApplication applicationToSynthese(Application app, Integer userId){

		SyntheseApplication syn = new SyntheseApplication();
		
		syn.setDateCreate(app.getDateCreate());
		syn.setDateMajStr(DateUtil.getDateView(app.getDateCreate()));
		
		syn.setId(app.getId());
		syn.setImage(app.getImage());
		syn.setLibelle(app.getLibelle());
		syn.setLien(app.getLien());
		syn.setMontant(app.getMontant());
		
		if(StatutApplication.DISPONIBLE.getCode().equals(app.getStatutApplication())){
			List<Participation> ops = psParticipation.readByParam(null, userId, app.getId());
			if(ops.isEmpty()){
				syn.setStatutApplication(StatutApplicationUser.DISPONIBLE.getCode());
				syn.setStatutApplicationLib(StatutApplicationUser.DISPONIBLE.getLibelle());
			}else if(ops.get(0).getStatutParticipation().equals(StatutParticipation.COMMENCEE.getCode())){
				syn.setStatutApplication(StatutApplicationUser.PARTICIPATION_ENCOURS_NOK.getCode());
				syn.setStatutApplicationLib(StatutApplicationUser.PARTICIPATION_ENCOURS_NOK.getLibelle());
			}else{
				syn.setStatutApplication(StatutApplicationUser.PARTICIPATION_ENCOURS_OK.getCode());
				syn.setStatutApplicationLib(StatutApplicationUser.PARTICIPATION_ENCOURS_OK.getLibelle());
			}
		}else{
			syn.setStatutApplication(StatutApplicationUser.EPUISEE.getCode());
			syn.setStatutApplicationLib(StatutApplicationUser.EPUISEE.getLibelle());
		}
		
		return syn;

	}

	public Boolean participerAction(Integer userId , Integer appId){

		Participation op;
		
		List<Participation> ops = psParticipation.readByParam(null,userId, appId);
		if(ops.isEmpty()){
			
			op = new Participation();
			
			op.setDateMaj(null);
			op.setDateCreate(new Date());
			op.setIdApplication(appId);
			op.setIdUser(Constantes.USER);
			op.setStatutParticipation(StatutParticipation.COMMENCEE.getCode());
			
			psParticipation.createObject(op);
			
			return true;
		
		}else{
			
			return false;
		
		}
		
	}

	public boolean updateApplication(Integer id, String lien, String libelle,
			BigDecimal montant, Integer statut, String logo) {
		
		Application app = psApp.readObject(id);

		app.setLibelle(libelle);
		app.setLien(lien);
		app.setMontant(montant);
		app.setStatutApplication(statut);
		app.setDateCreate(new Date());
		app.setImage(logo);

		psApp.updateObject(app);
		return true;
	
	}

	public boolean deleteApplication(Integer id) {
		Application app = psApp.readObject(id);
		psApp.deleteObject(app);
		return true;
	}

	public boolean createApplication(String logo, String lien, String libelle,
			BigDecimal montant, Integer statut) {
		Application app = new Application();
		app.setLibelle(libelle);
		app.setImage(logo);
		app.setLien(lien);
		app.setMontant(montant);
		app.setStatutApplication(statut);
		app.setDateCreate(new Date());
		
		app.setQuestion("Question todo");
		app.setProposition1("todo proposition1");
		app.setProposition2("todo proposition2");
		app.setProposition3("todo proposition3");
		app.setProposition4("todo proposition4");
		app.setReponse(NB5);
		
		psApp.createObject(app);
		return true;
	}

	public void updateStatutsApplications(SyntheseEcranApplications ecran) {
		List<Application> apps = psApp.readAllObject();
		for(Application app: apps){
			app.setLibelle(ecran.getMapLibelle().get(app.getId()));
			app.setLien(ecran.getMapLien().get(app.getId()));
			app.setMontant(ecran.getMapMontant().get(app.getId()));
			app.setStatutApplication(ecran.getMapStatuts().get(app.getId()));
			app.setImage(ecran.getMapLogo().get(app.getId()));
			app.setDateCreate(new Date());
			psApp.updateObject(app);
		}
	}

	public boolean updateApplicationMoa(Integer id, Integer statut) {
		Application app = psApp.readObject(id);
		app.setStatutApplication(statut);
		app.setDateCreate(new Date());
		psApp.updateObject(app);
		return true;
	}

	public void updateStatutsApplicationsMoa(SyntheseEcranApplications ecran) {
		List<Application> apps = psApp.readAllObject();
		for(Application app: apps){
			app.setStatutApplication(ecran.getMapStatuts().get(app.getId()));
			app.setDateCreate(new Date());
			psApp.updateObject(app);
		}
	}

	public List<Application> getApplicationsByStatut(Integer statutRecherche) {
		return psApp.readByStatut(statutRecherche);
	}

	public boolean validerParticiperAction(Integer user, Integer idApp,	SyntheseEcranParticipation ecranPart) {
		Participation op;
		
		List<Participation> ops = psParticipation.readByParam(null,user, idApp);

		if(!ops.isEmpty()){
			op = ops.get(0);
			op.setDateMaj(new Date());
			op.setReponse(ecranPart.getReponse());
			op.setReponse1(ecranPart.getReponse1());
			op.setReponse2(ecranPart.getReponse2());
			op.setReponse3(ecranPart.getReponse3());
			op.setReponse4(ecranPart.getReponse4());
			op.setReponse5(ecranPart.getReponse5());
			op.setReponse6(ecranPart.getReponse6());
			op.setReponse7(ecranPart.getReponse7());
			op.setStatutParticipation(StatutParticipation.VALIDEE.getCode());
			psParticipation.createObject(op);
			return true;
		}else{
			return false;
		}
		
	}

	public Application readObject(Integer idApp) {
		return psApp.readObject(idApp);
	}
	
	
	public Map<Integer,String> getMapStatutsApplication(){
		Map<Integer,String> mapStatut = new HashMap<Integer,String>();
		for(StatutApplication statut : StatutApplication.values()){
			mapStatut.put(statut.getCode(),statut.getLibelle());
		}
		return mapStatut;
	}
	
	public void prepareDate(Integer idApp,Map<String, Object> map) {
		Map<Integer,String> propositions1 = new HashMap<Integer,String>();
		propositions1.put(NB1,NB1.toString());
		propositions1.put(NB2,NB2.toString());
		propositions1.put(NB3,NB3.toString());
		propositions1.put(NB4,NB4.toString());
		propositions1.put(NB5,NB5.toString());
		
		Map<Integer,String> propositions2 = new HashMap<Integer,String>();
		propositions2.put(NB1,OUI);
		propositions2.put(NB2,NON);
		
		Application app = readObject(idApp);
	
		map.put("question", app.getQuestion());
		map.put("proposition1", app.getProposition1());
		map.put("proposition2", app.getProposition2());
		map.put("proposition3", app.getProposition3());
		map.put("proposition4", app.getProposition4());
	
		map.put("propositions1", propositions1);
		map.put("propositions2", propositions2);
	}
	
	

}
